package com.lenovo.lcdm.dcm.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lenovo.lcdm.dcm.dto.PortfolioOfferingQueryDto;
import com.lenovo.lcdm.dcm.dto.PortfolioOfferingQueryOptionsDto;
import com.lenovo.lcdm.dcm.dto.ReferencedProductInLastYearDto;
import com.lenovo.lcdm.dcm.entity.PortfolioOffering;
import com.lenovo.lcdm.dcm.mapper.PortfolioOfferingMapper;
import com.lenovo.lcdm.dcm.service.CtoCVService;
import com.lenovo.lcdm.dcm.service.PortfolioOfferingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author sunby1
* @description 针对表【integration_portfolio_offering】的数据库操作Service实现
* @createDate 2024-01-18 10:43:45
*/
@Service
public class PortfolioOfferingServiceImpl extends ServiceImpl<PortfolioOfferingMapper, PortfolioOffering>
    implements PortfolioOfferingService{

    @Autowired
    private CtoCVService ctoCVService;

    @Override
    public PortfolioOfferingQueryOptionsDto getAllQueryOptions() {
        PortfolioOfferingQueryOptionsDto dto = new PortfolioOfferingQueryOptionsDto();
        dto.setProductSegments(getDistinctColumnOptions("product_segment"));
        dto.setBusinessSegments(getDistinctColumnOptions("business_segment"));
        dto.setBusinessUnits(getDistinctColumnOptions("business_unit"));
        dto.setBrands(getDistinctColumnOptions("brand"));
        dto.setFormFactors(getDistinctColumnOptions("form_factor"));
        dto.setCategories(getDistinctColumnOptions("category"));
        dto.setPlanningCycles(getDistinctColumnOptions("project_planning_cycle"));
        return dto;
    }

    @Override
    public Set<String> getDistinctColumnOptions(String columnName){
        Set<String> optionSet = new HashSet<>();
        QueryWrapper<PortfolioOffering> qw = Wrappers.query();
        qw.select("distinct " + columnName).ge("project_planning_cycle", "FY 22/23").orderByDesc(columnName);
        List<String> list = this.listObjs(qw);
        if(CollectionUtils.isNotEmpty(list)){
            optionSet = list.stream().filter(i->i != null && !i.equals("N/A") && !i.equals("")).collect(Collectors.toSet());
        }
        return optionSet;
    }

    @Override
    public List<PortfolioOffering> getPortfolioOfferingList(Page page, PortfolioOfferingQueryDto dto) {
        QueryWrapper<PortfolioOffering> qw = new QueryWrapper<>();
        qw.select(PortfolioOffering.class, info -> !info.getColumn().equals("json_data"));
        if(CollectionUtils.isNotEmpty(dto.getProductSegments())){
            qw.in("product_segment", dto.getProductSegments());
        }
        if(CollectionUtils.isNotEmpty(dto.getBusinessSegments())){
            qw.in("business_segment" , dto.getBusinessSegments());
        }
        if(CollectionUtils.isNotEmpty(dto.getBusinessUnits())){
            qw.in("business_unit", dto.getBusinessUnits());
        }
        if(CollectionUtils.isNotEmpty(dto.getBrands())){
            qw.in("brand", dto.getBrands());
        }
        if(CollectionUtils.isNotEmpty(dto.getFormFactors())){
            qw.in("form_factor", dto.getFormFactors());
        }
        if(CollectionUtils.isNotEmpty(dto.getCategories())){
            qw.in("category", dto.getCategories());
        }
        if(CollectionUtils.isNotEmpty(dto.getPlanningCycles())){
            qw.in("project_planning_cycle", dto.getPlanningCycles());
        }else{
            qw.ge("project_planning_cycle", "FY 22/23");
        }
        if(StringUtils.isNotEmpty(dto.getOfferingName())){
            qw.like("lower(offering_name)", dto.getOfferingName().toLowerCase());
        }
        if(StringUtils.isNotEmpty(dto.getPortfolioName())){
            qw.like("lower(portfolio_name)", dto.getPortfolioName().toLowerCase());
        }
        if(StringUtils.isNotEmpty(dto.getPlatformInfo())){
            qw.like("lower(platform_info)", dto.getPlatformInfo().toLowerCase());
        }
        if(StringUtils.isNotEmpty(dto.getScreenSize())){
            qw.like("lower(screen_size)", dto.getScreenSize().toLowerCase());
        }
        if(StringUtils.isNotEmpty(dto.getChassisSize())){
            qw.like("lower(chassis_size)", dto.getChassisSize().toLowerCase());
        }
        if(StringUtils.isNotEmpty(dto.getLastGenProduct())){
            qw.like("lower(last_gen_product)", dto.getLastGenProduct().toLowerCase());
        }
        return this.list(page, qw);
    }

    @Override
    public List<ReferencedProductInLastYearDto> getReferencedProductInLastYear(List<String> productOfferingNames) {
        List<ReferencedProductInLastYearDto> list = new ArrayList<>();
        if(CollectionUtils.isEmpty(productOfferingNames)){
            return list;
        }
        LambdaQueryWrapper<PortfolioOffering> qw = new LambdaQueryWrapper<>();
        qw.in(PortfolioOffering::getOfferingName, productOfferingNames);
        List<PortfolioOffering> offeringList = this.list(qw);
        if(CollectionUtils.isNotEmpty(offeringList)){
            list = offeringList.stream().map(offering -> {
                ReferencedProductInLastYearDto dto = new ReferencedProductInLastYearDto();
                dto.setProductOfferingName(offering.getOfferingName());
                if(StringUtils.isNotEmpty(offering.getLastGenProduct()) && !"N/A".equals(offering.getLastGenProduct())) {
                    dto.setReferencedProductInLastYear(offering.getLastGenProduct());
                    List<String> ctoList = getReferencedCtoByProductName(offering.getLastGenProduct());
                    if(CollectionUtils.isNotEmpty(ctoList)){
                        dto.setReferencedCtoInLastYear(ctoList.stream().collect(Collectors.joining(",")));
                    }else {
                        dto.setReferencedCtoInLastYear("");
                    }
                }else if("N/A".equals(offering.getLastGenProduct())) {
                    dto.setReferencedProductInLastYear("N/A");
                    dto.setReferencedCtoInLastYear("");
                }else{
                    dto.setReferencedProductInLastYear("");
                    dto.setReferencedCtoInLastYear("");
                }
                return dto;
            }).collect(Collectors.toList());
        }
        return list;
    }

    @Override
    public List<String> getReferencedCtoByProductName(String productOfferingName) {
        List<String> ctoNumList = new ArrayList<>();
        LambdaQueryWrapper<PortfolioOffering> qw = new LambdaQueryWrapper<>();
        qw.eq(PortfolioOffering::getOfferingName, productOfferingName);
        PortfolioOffering offering = this.getOne(qw, false);
        if(offering == null){
            return ctoNumList;
        }
        JSONObject jsonObject = JSONUtil.parseObj(offering.getJsonData());
        //没有phCode返回空
        Object phCodeObj = jsonObject.get("phCode");
        if(phCodeObj == null){
            return ctoNumList;
        }
        String[] phCodeArr = phCodeObj.toString().split(",");
        for(int i=0; i<phCodeArr.length; i++){
            //phCode不是18位返回空
            if(phCodeArr[i].length() < 18){
                continue;
            }
            String machineType = phCodeArr[i].substring(11,15);
            ctoNumList.addAll(ctoCVService.getByMachineType(machineType));
        }

        return ctoNumList;
    }

    @Override
    public List<String> getAllPortfolioOfferingName() {
        QueryWrapper<PortfolioOffering> qw = new QueryWrapper();
        qw.select("distinct offering_name");
        return this.listObjs(qw);
    }

    @Override
    public List<PortfolioOffering> fetchUserListByUsername(String username) {
        Page<PortfolioOffering> page = new Page<>(1, 100);
        QueryWrapper<PortfolioOffering> query = Wrappers.query();
        query.likeRight("LOWER(offering_name)", username.toLowerCase());
        query.orderByAsc("offering_name");
        return this.list(page, query);
    }
}




